package com.zhixiang.core.util;

import com.alibaba.druid.pool.DruidAbstractDataSource;

import org.hibernate.SQLQuery;
import org.hibernate.Session;

import java.io.*;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * @author whw
 * @version v1.0
 * @date 2015/12/8
 */
public class BackupUtils {
    private static String username;
    private static String password;
    private static String databaseIP;
    private static String databaseName;
    private static String mysqlHome;

    /**
     * 初始化变量
     */
    static {
        DruidAbstractDataSource dataSource = WebUtils.getDataSource();
        username = dataSource.getUsername();
        password = dataSource.getPassword();

//        String url = "jdbc:mysql://127.0.0.1:3306/limsdb?useUnicode=true&characterEncoding=UTF-8";
        String url = dataSource.getUrl();
        String regex = ".*//(.*):\\d*/(.*)\\?.*";
        Pattern pattern = Pattern.compile(regex);
        Matcher matcher = pattern.matcher(url);
        while(matcher.find()){
            databaseIP = matcher.group(1);
            databaseName = matcher.group(2);
        }
//        databaseIP = "localhost";
//        databaseName = "limsdb";

        Session session = WebUtils.getSessionFactory().openSession();
        SQLQuery sqlQuery =session.createSQLQuery("select @@basedir as basePath from dual");
        @SuppressWarnings("unchecked")
		List<Object> list = sqlQuery.list();
        Object obj = list.get(0);
        mysqlHome = String.valueOf(obj);
//        mysqlHome = String.valueOf(obj).replaceAll(" ","\" \"");
//        mysqlHome = "D:\\ProgramSoft\\mysql-5.6.26-winx64";
    }

    public static void backup(OutputStream outputStream) throws IOException {
        System.out.println("开始备份...");
        Runtime rt = Runtime.getRuntime();
        // 调用 调用mysql的安装目录的命令

//      String cmd = "cmd /c " +mysqlHome + "/bin/mysqldump.exe "+databaseName+" -h"+databaseIP+" -u"+username+" -p"+password;
//      Process child = rt.exec(cmd);
        
//        String cmd = "mysqldump.exe -h"+databaseIP+" -u"+username+" -p"+password+ " " + databaseName;
//        Process child = rt.exec(cmd, null,new File(mysqlHome+"/bin"));
        
        Process child = rt.exec(new String[]{mysqlHome + "/bin\\mysqldump.exe","-h",databaseIP,"-u"+username,"-p"+password,databaseName});

//        Process child = rt.exec("cmd.exe /c "+mysqlHome + "\\bin\\mysqldump.exe -h "+databaseIP+" -u"+username+" -p"+password+" "+databaseName);
        
        // 设置导出编码为utf-8。这里必须是utf-8
        // 把进程执行中的控制台输出信息写入.sql文件，即生成了备份文件。注：如果不对控制台信息进行读出，则会导致进程堵塞无法运行
        InputStream inputStream = child.getInputStream();// 控制台的输出信息作为输入流
        InputStreamReader inputStreamReader = new InputStreamReader(inputStream, "utf-8");
        // 设置输出流编码为utf-8。这里必须是utf-8，否则从流中读入的是乱码
        String inStr;
        StringBuffer sb = new StringBuffer("");
        String outStr;
        // 组合控制台输出信息字符串
        BufferedReader bufferedReader = new BufferedReader(inputStreamReader);
        while ((inStr = bufferedReader.readLine()) != null) {
            sb.append(inStr + "\r\n");
        }
        outStr = sb.toString();
        // 要用来做导入用的sql目标文件：
        OutputStreamWriter writer = new OutputStreamWriter(outputStream, "utf-8");
        writer.write(outStr);
        writer.flush();
        inputStream.close();
        inputStreamReader.close();
        bufferedReader.close();
        writer.close();
        outputStream.close();
        System.out.println("备份结束...");
    }

    public static void backup(String backupPath) throws IOException {
        OutputStream outputStream = new FileOutputStream(backupPath);
        backup(outputStream);
    }

    public static void restore(InputStream input) throws IOException {
        System.out.println("开始还原...");
        Runtime rt = Runtime.getRuntime();

        // 调用 mysql 的 cmd:
        Process child = rt.exec(mysqlHome + "/bin\\mysql -u"+username+" -p"+password+" "+databaseName);
        
//      String cmd = mysqlHome + "/bin/mysql.exe -u"+username+" -p"+password+" "+databaseName;
        
//      String cmd = "mysql.exe -u"+username+" -p"+password+" "+databaseName;
//      Process child = rt.exec(cmd,null,new File(mysqlHome+"/bin"));
      
        OutputStream out = child.getOutputStream();//控制台的输入信息作为输出流
        String inStr;
        StringBuffer sb = new StringBuffer("");
        String outStr;
        BufferedReader br = new BufferedReader(new InputStreamReader(input, "utf8"));
        while ((inStr = br.readLine()) != null) {
            sb.append(inStr + "\r\n");
        }
        outStr = sb.toString();

        OutputStreamWriter writer = new OutputStreamWriter(out, "utf8");
        writer.write(outStr);
        // 注：这里如果用缓冲方式写入文件的话，会导致中文乱码，用flush()方法则可以避免
        writer.flush();
        // 别忘记关闭输入输出流
        out.close();
        br.close();
        writer.close();
        System.out.println("还原结束...");
    }

    public static void restore(String fileUrl) {
        try {
            InputStream input = new FileInputStream(fileUrl);
            restore(input);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}
